﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Moq;
using FriendsNearby.Services;
using System.ComponentModel.Design;
using FriendsNearby.Services.Entities;
using Twitter.Tests;
using Twitter;

namespace FriendsNearbyBot.Tests
{
    [TestFixture]
    public class FriendsQueryProcessorFixture : TestBase
    {
        IServiceProvider services;
        Mock<IPeopleNearbyService> peopleNearbyService;
        Mock<IUsersService> usersService;

        [SetUp]
        public void CreateServices()
        {
            var services = new ServiceContainer();
            this.services = services;

            peopleNearbyService = new Mock<IPeopleNearbyService>();
            usersService = new Mock<IUsersService>();
            services.AddService(peopleNearbyService.Object);
            services.AddService(usersService.Object);
        }

        [Test]
        public void ShouldListAllDirectFriends()
        {
            usersService.Expect(x => x.GetFacebookUserIdFromTwitter("fnbtestb")).Returns("b_facebookid");
            peopleNearbyService.Expect(x => x.GetAllFriends("b_facebookid")).Returns(new PersonNearby[]{
                new PersonNearby() { DisplayName = "user1" , Distance = 1 },
                new PersonNearby() { DisplayName = "user2" , Distance = 2 }
            });

            // Warn: 
            MemoryBotClient bot = new MemoryBotClient("fnb");
            MemoryBotClient user = new MemoryBotClient("fnbtestb");
            bot.SetBuddy(user);
            user.SetBuddy(bot);

            FriendsQueryProcessor processor = new FriendsQueryProcessor(services, CreateMessageBuilder());
            processor.Process(bot, CreateMessage("list all", user.ScreenName, bot.ScreenName));

            Assert.AreEqual(1, user.Messages.GetAll().Count());
            AssertString.StartsWith("user1:1 Km.;", user.Messages.GetAll().First().Text);
        }

        [Test]
        public void ShouldDoLikeSearchBetweenFriends()
        {
            usersService.Expect(x => x.GetFacebookUserIdFromTwitter("fnbtestb")).Returns("b_facebookid");
            peopleNearbyService.Expect(x => x.GetAllFriends("b_facebookid")).Returns(new PersonNearby[]{
                new PersonNearby() { DisplayName = "Another User" , Distance = 1 },
                new PersonNearby() { DisplayName = "Joanne Goldstein" , Distance = 1 },
                new PersonNearby() { DisplayName = "Edward Johanson" , Distance = 2 },
                new PersonNearby() { DisplayName = "Harry" , Distance = 3 },
                new PersonNearby() { DisplayName = "Jo Smith" , Distance = 4 }
            });

            // Warn: 
            MemoryBotClient bot = new MemoryBotClient("fnb");
            MemoryBotClient user = new MemoryBotClient("fnbtestb");
            bot.SetBuddy(user);
            user.SetBuddy(bot);

            FriendsQueryProcessor processor = new FriendsQueryProcessor(services, CreateMessageBuilder());
            processor.Process(bot, CreateMessage("search jo", user.ScreenName, bot.ScreenName));

            Assert.AreEqual(1, user.Messages.GetAll().Count());
            Assert.That(user.Messages.GetAll().First().Text.Contains("Joanne Goldstein:1 Km.;"));
            Assert.That(user.Messages.GetAll().First().Text.Contains("Edward Johanson:2 Km.;"));
            Assert.That(user.Messages.GetAll().First().Text.Contains("Jo Smith:4 Km.;"));
            Assert.IsFalse(user.Messages.GetAll().First().Text.Contains("Another User"));
            Assert.IsFalse(user.Messages.GetAll().First().Text.Contains("Harry"));
        }

        [Test]
        public void RandomMessageAllowsNextProccessor()
        {
            // Warn: 
            MemoryBotClient bot = new MemoryBotClient("fnb");
            MemoryBotClient user = new MemoryBotClient("fnbtestb");
            bot.SetBuddy(user);
            user.SetBuddy(bot);

            FriendsQueryProcessor processor = new FriendsQueryProcessor(services, CreateMessageBuilder());
            var result = processor.Process(bot, CreateMessage("blah", user.ScreenName, bot.ScreenName));
            Assert.AreEqual(RunNextProcessor.Yes, result);

            Assert.AreEqual(0, user.Messages.GetAll().Count());
        }

        [Test]
        public void SearchWithoutCriteriaProduceNoMessage()
        {
            // Warn: 
            MemoryBotClient bot = new MemoryBotClient("fnb");
            MemoryBotClient user = new MemoryBotClient("fnbtestb");
            bot.SetBuddy(user);
            user.SetBuddy(bot);

            FriendsQueryProcessor processor = new FriendsQueryProcessor(services, CreateMessageBuilder());

            var result = processor.Process(bot, CreateMessage("search", user.ScreenName, bot.ScreenName));
            Assert.AreEqual(RunNextProcessor.Yes, result);

            Assert.AreEqual(0, user.Messages.GetAll().Count());
        }

        [Test]
        public void SearchNotNormalizedWithoutCriteriaProduceNoMessage()
        {
            // Warn: 
            MemoryBotClient bot = new MemoryBotClient("fnb");
            MemoryBotClient user = new MemoryBotClient("fnbtestb");
            bot.SetBuddy(user);
            user.SetBuddy(bot);

            FriendsQueryProcessor processor = new FriendsQueryProcessor(services, CreateMessageBuilder());

            var result = processor.Process(bot, CreateMessage("  SeArch  ", user.ScreenName, bot.ScreenName));
            Assert.AreEqual(RunNextProcessor.Yes, result);

            Assert.AreEqual(0, user.Messages.GetAll().Count());
        }

        [Test]
        public void ShouldShowNiceEmptyMessage()
        {
            usersService.Expect(x => x.GetFacebookUserIdFromTwitter("fnbtestb")).Returns("b_facebookid");
            peopleNearbyService.Expect(x => x.GetAllFriends("b_facebookid")).Returns(new PersonNearby[]{
            });

            // Warn: 
            MemoryBotClient bot = new MemoryBotClient("fnb");
            MemoryBotClient user = new MemoryBotClient("fnbtestb");
            bot.SetBuddy(user);
            user.SetBuddy(bot);

            FriendsQueryProcessor processor = new FriendsQueryProcessor(services, CreateMessageBuilder());
            processor.Process(bot, CreateMessage("list all", user.ScreenName, bot.ScreenName));

            Assert.AreEqual(1, user.Messages.GetAll().Count());
            Assert.That(user.Messages.GetAll().First().Text.Contains("There are no people to list"));
        }
    }
}
